import aiomysql

from configs import config, errorCode
from views import BaseHandler
from models import execute, shopping_cart
from utils.util import json_decode


class ShoppingCart(BaseHandler):

    @BaseHandler.auth
    async def get(self):
        """
        ---
        tags:
          - 购物车
        summary: 查看购物车
        description:
        parameters:
        - in: cookie
          name: user_token
          schema:
            type: string
            default: null
        responses:
          '200':
            description: successful operation
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/OkModel'
          '400':
            description: error operation
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/ErrorModel'
        """
        user_id = self.current_user
        res = await config.redis.hgetall('user_cart:%s' % user_id)
        if not res:
            return self.write_error(errorCode.OK, '购物车没有商品,快去添加吧')
        cart_dict = {}
        for sku_id, count in res.items():
            cart_dict[int(sku_id)] = {
                'count': int(count),
            }
        sku_id_list = cart_dict.keys()
        skus = await shopping_cart.get_cart_all_sku(sku_id_list)
        cart_skus = []
        for sku in skus:
            property_values = await shopping_cart.get_property_value_from_sku_id(sku)
            self.generate_data(cart_skus, sku, cart_dict, property_values)
        return self.write_json(data=cart_skus)

    @BaseHandler.auth
    async def post(self):
        """
        ---
        tags:
          - 购物车
        summary: 添加购物车
        description:
        requestBody:
          description: spu_id的值只能传5到8之间
          content:
            application/json:
                schema:
                  type: object
                  properties:
                    spu_id:
                      type: integer
                    count:
                        type: integer
                    property_values:
                        type: array
        responses:
          '200':
            description: successful operation
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/OkModel'
          '400':
            description: error operation
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/ErrorModel'
        """
        # 接收参数
        spu_id, count, property_values = self.get_user_argument()

        # 校验参数
        if not all([spu_id, count, property_values]):
            return self.write_error(errorCode.INVALID_ARGS, desc='缺少必要参数')

        spu = await shopping_cart.query_goods_is_exist(spu_id)
        if not spu:
            return self.write_error(errorCode.INVALID_ARGS, desc='参数spu_id不存在')

        try:
            count = int(count)
        except Exception as e:
            return self.write_error(errorCode.INVALID_ARGS, desc='参数count错误')

        # 通过spu_id获取所有它下面的sku_id
        sku_ids = await shopping_cart.query_sku_from_spu(spu_id)

        # 把sku_ids解析成一个列表
        new_sku_ids = []
        for i in sku_ids:
            new_sku_ids.append(i['id'])
        sku_id_count = len(new_sku_ids)

        # 判断property参数有没有少或多
        res = await shopping_cart.query_spu_property_count(sku_id_count, new_sku_ids)
        if len(property_values) != int(res[0].get('total')):
            return self.write_error(errorCode.INVALID_ARGS, desc='缺少必要参数')

        # 通过前传来的spu_id和property属性来查到唯一的sku_id
        sku_set = await self.query_sku_from_spu_property(property_values, sku_id_count, new_sku_ids)
        try:
            sku_id = list(sku_set)[0]
        except Exception as e:
            self.logger.error(e)
            return self.write_error(errorCode.NOT_GOODS, '商品不存在')
        await config.redis.hincrby('user_cart:%s' % self.current_user, sku_id, count)
        return self.write_json()

    async def query_sku_from_spu_property(self, property_values, sku_id_count, new_sku_ids):
        sku_set = []
        for i in property_values:
            sku_list = []
            new_sku_ids.append(i)
            res = await shopping_cart.query_sku_from_property_title_skus(sku_id_count, new_sku_ids)
            for j in res:
                sku_list.append(j['sku_id'])
            if not sku_set:
                sku_set = set(sku_list)
            else:
                sku_set = sku_set & set(sku_list)
            del new_sku_ids[-1]
        return sku_set

    def get_user_argument(self):
        json_dict = json_decode(self.request.body)
        spu_id = json_dict.get('spu_id')
        count = json_dict.get('count')
        property_values = json_dict.get('property_values')
        return spu_id, count, property_values

    def generate_data(self, cart_skus, sku, cart_dict, property_values):
        cart_skus.append({
            'id': sku.get('id'),
            'count': cart_dict.get(sku.get('id')).get('count'),
            'name': sku.get('title'),
            'price': float(sku.get('price')),
            'amount': float(sku.get('price') * cart_dict.get(sku.get('id')).get('count')),
            'default_image': config.IMG_PATH + sku.get('default_image'),
            'property_values': property_values
        })


class DeleteCart(BaseHandler):

    @BaseHandler.auth
    async def post(self, *args, **kwargs):
        """
        ---
        tags:
          - 购物车
        summary: 删除购物车
        description:
        parameters:
        - in: cookie
          name: user_token
          schema:
            type: string
            default: null
        requestBody:
          description:
          content:
            application/json:
                schema:
                  type: object
                  properties:
                    sku_id:
                        type: array
        responses:
          '200':
            description: successful operation
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/OkModel'
          '400':
            description: error operation
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/ErrorModel'
        """

        # 接收参数
        json_dict = json_decode(self.request.body)
        sku_id_list = json_dict.get('sku_id')

        # 判断sku_id是否存在

        sku = await shopping_cart.query_sku_is_exist(sku_id_list)
        if not sku:
            return self.write_error(errorCode.INVALID_ARGS, desc='参数sku_id不存在')
        await config.redis.hdel('user_cart:%s' % self.current_user, *sku_id_list)
        return self.write_json()


class PutCart(BaseHandler):

    @BaseHandler.auth
    async def post(self):
        """
        ---
        tags:
          - 购物车
        summary: 修改购物车
        description:
        parameters:
        - in: cookie
          name: user_token
          schema:
            type: string
            default: null
        requestBody:
          description:
          content:
            application/json:
                schema:
                  type: object
                  properties:
                    sku_id:
                        type: integer
                    count:
                        type: integer
        responses:
          '200':
            description: successful operation
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/OkModel'
          '400':
            description: error operation
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/ErrorModel'
        """

        # 接收参数
        json_dict = json_decode(self.request.body)
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        # 校检参数
        if not all([sku_id, count]):
            return self.write_error(errorCode.INVALID_ARGS, desc='缺少必要参数')

        sku = await shopping_cart.query_sku_is_exist(sku_id)
        if not sku:
            return self.write_error(errorCode.INVALID_ARGS, desc='参数sku_id不存在')
        sku = sku[0]
        try:
            count = int(count)
        except Exception as e:
            self.logger.error(e)
            return self.write_error(errorCode.INVALID_ARGS, desc='参数count错误')
        res = await config.redis.hget('user_cart:%s' % self.current_user, sku_id)
        if not res:
            return self.write_error(errorCode.INVALID_ARGS, desc='参数sku_id无效')
        await config.redis.hset('user_cart:%s' % self.current_user, sku_id, count)
        # 创建响应对象
        # cart_sku = {
        #     'id': sku_id,
        #     'count': count,
        #     'name': sku.get('title'),
        #     'price': float(sku.get('price')),
        #     'amount': float(sku.get('price')) * count,
        #     'default_image': 'http://81.71.137.167:8000/content/' + sku.get('default_image')
        # }
        # return self.write_json(data=cart_sku)
        return self.write_json()


class CartIsSelectedAll(BaseHandler):

    async def put(self, *args, **kwargs):
        # 接收参数
        json_dict = json_decode(self.request.body)
        selected = json_dict.get('selected')
        print(selected, type(selected))
        # 校验参数
        if selected:
            if not isinstance(selected, bool):
                return self.write_error(errorCode.INVALID_ARGS, '参数selected有误')
        # 判断用户是否登录

        res = await config.redis.hgetall('user_id')
        sku_ids = res.keys()
        print(sku_ids)
        if selected:
            await config.redis.sadd('selected_user_id', *sku_ids)
        else:
            await config.redis.srem('selected_user_id', *sku_ids)
        return self.write_json()






